﻿namespace MonetDbDataProvider.Security
{
    using System;
    using System.Linq;
    using System.Security.Cryptography;

    public class CryptoProvider : ICryptoProvider
    {
        public HashResult ComputeHash(byte[] bytes, string provider)
        {
            return this.ComputeHash(bytes, new[] { provider });
        }

        public HashResult ComputeHash(byte[] bytes, string[] availableProviders)
        {
            var bHash = new byte[0];
            var provider = string.Empty;

            foreach (var availableProvider in availableProviders)
            {
                switch (availableProvider)
                {
                    case "SHA512":
                        var sha512 = new SHA512CryptoServiceProvider();
                        bHash = sha512.ComputeHash(bytes);
                        provider = "SHA512";
                        break;
                    case "SHA384":
                        var sha384 = new SHA384CryptoServiceProvider();
                        bHash = sha384.ComputeHash(bytes);
                        provider = "SHA384";
                        break;
                    case "SHA256":
                        var sha256 = new SHA256CryptoServiceProvider();
                        bHash = sha256.ComputeHash(bytes);
                        provider = "SHA256";
                        break;
                    case "SHA1":
                        var sha1 = new SHA1CryptoServiceProvider();
                        bHash = sha1.ComputeHash(bytes);
                        provider = "SHA1";
                        break;
                    case "MD5":
                        var md5 = new MD5CryptoServiceProvider();
                        bHash = md5.ComputeHash(bytes);
                        provider = "MD5";
                        break;
                }

                if (bHash.Length > 0) break;
            }

            if (bHash.Length == 0 || string.IsNullOrEmpty(provider))
                throw new ArgumentException("Provider does not support any of the server's hashing libraries.");

            return new HashResult()
                       {
                           HashType = provider,
                           Hash = bHash,
                           HexHash = string.Concat(bHash.Select(b => b.ToString("x2")))
                       };
        }
    }
}
